/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package services;

import dao.SubmissionJpaController;
import entities.Problem;
import entities.Run;
import entities.Submission;
import entities.TestCase;
import entities.User;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import util.CompileAndExecuteAllTestCase;
import util.EnumVerdicts;
import util.VerdictOutput;

public class SubmissionService {
    private static SubmissionJpaController sc;
    private static ProblemService ps;
    private static UserService us;

    private SubmissionJpaController getJPAController()
    {
        if(sc == null)
            sc = new SubmissionJpaController();
        return sc;
    }


    private ProblemService getProblemService()
    {
        if(ps == null)
            ps = new ProblemService();
        return ps;
    }

    private UserService getUserService()
    {
        if(us == null)
            us = new UserService();
        return us;
    }

    public boolean saveSubmission(Submission s)
    {
        boolean ret = true;
        sc = getJPAController();
        try
        {
            sc.create(s);
        }
        catch (Exception e)
        {
            ret = false;
        }
        return ret;
    }

    Submission getSubmission(int idSubmission)
    {
        sc = getJPAController();
        return sc.findSubmission(idSubmission);
    }

    public List<Submission> getSubmissionsByUser(User user)
    {
        sc = getJPAController();
        return sc.findSubmissionsByUser(user);
    }

    public VerdictOutput processSubmission(final Submission submission , ArrayList<TestCase> testCaseList)
    {
        if( testCaseList == null )System.out.println("Ojo ArrayList<TestCase> testCaseList == null en SubmissionService.java");
        if( submission == null )System.out.println("Ojo Submission submission == null en SubmissionService.java");

        //System.out.println("en SubmissionService.java.processSubmission "+handle);
        //sf = new ServiceFactory();
        //ts = sf.getTestcaseService();
        //rs = sf.getRunService();
        //ps = sf.getProblemService();

        //prob = ps.find(idProb);
        Problem prob = submission.getProblem();
        //Submission submit = new Submission();
        //Crea la submission
        //create(code, language, dateTime,EnumVerdicts.UE.value(), handle, idProb);
        //comp = cmps.find(handle) ;
        User comp = submission.getUser();
        //submit = getSubmissionByDateAndHandle(comp, dateTime);
        if( prob == null )System.out.println("Ojo Problem prob == null en SubmissionService.java");
        if( comp == null )System.out.println("Ojo User comp == null en SubmissionService.java");

        Vector<TestCase> testcases =  (Vector<TestCase>) prob.getTestCaseCollection();
        int total = testcases.size();
        CompileAndExecuteAllTestCase cae = new CompileAndExecuteAllTestCase(prob, testcases, comp, submission);
        VerdictOutput ret = new VerdictOutput();
        int acceptedRuns = 0;
        if(cae.isSuccessfullyCompiled()){
            //System.out.println("en SubmissionService.java.processSubmission en if de que compilÛ");
            cae.runTestCases();
            Vector<Run> rns = cae.getRuns();
            submission.setVerdict(cae.getVerdict());
            ret.setCode( cae.getSourceCode());
            ret.setCompileOutput( cae.getCompilationOutput());
            ret.setExecutionOutput( cae.getExecutionOutput());

            for (int i =0;i<rns.size();i++) {
                //Crea la run
                //rs.create(rns.get(i).getVerdict(), rns.get(i).getOutput(),testcases.get(i).getIdTestCase() , submit.getIdSubmission(), rns.get(i).getTime());
                ret.addRun(rns.get(i));
                if( rns.get(i).getVerdict().equalsIgnoreCase( EnumVerdicts.AC.value() ) )
                {
                    acceptedRuns = 0;
                }
            }
            ret.setCompileOutput(cae.getCompilationOutput());

        }
        else{
            submission.setVerdict(EnumVerdicts.CE.value());
            ret.setCompileOutput(cae.getCompilationOutput());
        }
        //Actualiza la submission
        //update(submit);
        ret.setVerdict(submission.getVerdict());
        //System.out.println("En SubmissionService.java.processSubmission, al final: Veredicto: "+cae.getVerdict());
        ret.setPercentTestCaseAccepted( 100.0*acceptedRuns/(double)total);
        System.out.println(ret.toString());
        return ret;
    }

}
